/**
 * Copyright 2012 Ricardo Engel
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.mookt.dcubed;

import java.io.Serializable;

/**
 * Value object is a small object that represents a simple entity whose equality
 * isn't based on identity, i.e. two value objects are equal when they have the
 * same value, not necessarily being the same object.
 * 
 * <p>
 * Per the above definition, the following is required to keep value objects
 * immutable:
 * <ul>
 * <li>Don't provide any methods that modify the object's state.</li>
 * <li>Ensure that the value object can't be extended by either making the class
 * final or the constructor to be private.</li>
 * <li>Make all fields final.</li>
 * <li>Make all fields private.</li>
 * <li>Ensure exclusive access to any mutable components or make defensive
 * copies if an exclusive access cannot be obtained.</li>
 * </ul>
 * In addition, all value objects must implement the {@link Object#hashCode()}
 * and {@link Object#equals(Object)} methods. It is also considered good
 * practice to re-implement the {@link Object#toString()} method. Value objects
 * that intrinsically have a natural order, e.g. Dates, should also implement
 * the {@link Comparable} interface.
 * </p>
 * 
 * <p>
 * If a value object has an internal member variable that is derived from other
 * attributes for performance purposes, then the same should be marked as
 * transient as per the Java Language Specification and should not be part of
 * the identity of this object.
 * </p>
 * 
 * @author Ricardo Engel
 */
public interface ValueObject extends Serializable {

    /**
     * Indicates whether some other object is "equal to" this value object.
     * 
     * <p>
     * This method must obey the general contract of
     * {@link Object#equals(Object)}. Additionally, this method can return
     * {@code true} <i>only</i> if the specified object is also a value object
     * and they have the same attributes. Thus, {@code o1.equals(o2)} implies
     * that {@code o1.attr.equals(o2.attr)} for every value object {@code o1}
     * and {@code o2} and attribute {@code attr}.
     * </p>
     * 
     * <p>
     * Note that this means that for every concrete implementation of this
     * interface, the {@link #equals(Object)} method has to be overwritten.
     * </p>
     * 
     * @param obj the reference object with which to compare.
     * @return <code>true</code> only if the specified object is also a value
     *         object and they have the same attributes.
     * @see Object#equals(Object)
     */
    @Override
    public boolean equals(Object obj);

    /**
     * Returns a hash code value for the value object. This method is supported
     * for the benefit of hash tables such as those provided by
     * {@link java.util.HashMap}.
     * 
     * <p>
     * This method must obey the general contract of {@link Object#hashCode())}.
     * Additionally, two value objects should have the same hash code
     * <i>only</i> if all their attributes also have the same hash code. Thus,
     * {@code o1.hashCode() == o2.hashCode()} implies that
     * {@code o1.attr.hashCode() == o2.attr.hashCode()} for every entity
     * reference {@code o1} and {@code o2} and attribute {@code attr}.
     * </p>
     * 
     * <p>
     * Note that this means that for every concrete implementation of this
     * interface, the {@link #hashCode()} method has to be overwritten.
     * </p>
     * 
     * @see Object#hashCode()
     * @return a hash code value for this object.
     */
    @Override
    public int hashCode();

}